DELETE /api/rbac/subjects/{uuid} has to repeat the
subject’s name and type as safeguard query parameters, which are
verified against the subject identified by the UUID in the path. If they
do not match, nothing is deleted: the request is rejected with
400 Bad Request and the API-key keeps authenticating.
| name | value |
|---|---|
| subjectUuid | a91c000c-0000-0000-0000-00000000000c |
| subjectName | revoke.attempt.key |
API_KEY subjects authenticate technical clients via the
Hostsharing-Api-Key HTTP header instead of a Keycloak OIDC
JWT, e.g. automation programs, completely bypassing Keycloak. Only a
global-admin may create API_KEY subjects. The clear-text API-key is
returned only once, in the response of creating the API_KEY subject;
just its hash gets stored. Like GROUP subjects, API_KEY subjects cannot
have an account. Global API_KEY subjects do not belong to a realm, thus
their name must neither contain a - (the realm-prefix
delimiter) nor a / (the GROUP subject marker).
The response contains the generated clear-text API-key (property
apiKey) exactly once; it cannot be retrieved again.
HTTP POST "/api/rbac/subjects" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }` \
<<EOF
{
"uuid" : "a91c000c-0000-0000-0000-00000000000c",
"name" : "revoke.attempt.key",
"type" : "API_KEY"
}
EOF
=> status: 201 CREATED a91c000c-0000-0000-0000-00000000000c
{
"uuid" : "a91c000c-0000-0000-0000-00000000000c",
"name" : "revoke.attempt.key",
"organization" : "revoke",
"type" : "API_KEY",
"apiKey" : "hsak_revoke.attempt.key.90b02708fd67d37f3b9a554b64d9aad1215a1166fa7574ab9d4b7bb97cc0bb7a",
"scopes" : null,
"expiresAt" : null
}
The grant API needs the UUID of the role which we want to grant.
HTTP GET "/api/rbac/roles?name=rbac.global%23global%3AADMIN" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }`
=> status: 200 OK
[ {
"uuid" : "589a6260-757d-4e3e-a2b7-08ca8b758868", // globalAdminRoleUuidToGrant
"object.uuid" : "9b7b3d20-a88f-4c19-8bc7-efdb8dd24832",
"objectTable" : "rbac.global",
"objectIdName" : "global",
"roleType" : "ADMIN",
"roleName" : "rbac.global#9b7b3d20-a88f-4c19-8bc7-efdb8dd24832:ADMIN",
"roleIdName" : "rbac.global#global:ADMIN"
} ]
HTTP POST "/api/rbac/grants" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }` \
-H 'Hostsharing-Assumed-Roles: rbac.global#global:ADMIN' \
<<EOF
{
"assumed" : true,
"grantedRole.uuid" : "589a6260-757d-4e3e-a2b7-08ca8b758868", // globalAdminRoleUuidToGrant
"granteeSubject.uuid" : "a91c000c-0000-0000-0000-00000000000c"
}
EOF
=> status: 201 CREATED 589a6260-757d-4e3e-a2b7-08ca8b758868 // globalAdminRoleUuidToGrant
HTTP GET "/api/hs/accounts/current" \
-H "Hostsharing-Api-Key: $HSADMINNG_API_KEY"
=> status: 200 OK
{
"subject" : {
"uuid" : "a91c000c-0000-0000-0000-00000000000c",
"name" : "revoke.attempt.key",
"organization" : "revoke",
"type" : "API_KEY"
},
"person" : null,
"globalAdmin" : true
}
HTTP DELETE "/api/rbac/subjects/a91c000c-0000-0000-0000-00000000000c?name=revoke.attempt.key.mismatch&type=API_KEY" \
-H "Authorization: Bearer $HSADMINNG_JWT_BEARER" \
`# {` \
`# "sub" : "uuid<hsh-alex_superuser>"` \
`# }`
=> status: 400 BAD_REQUEST
{
"timestamp" : "2026-08-10 03:08:49",
"path" : "",
"statusCode" : 400,
"statusPhrase" : "Bad Request",
"message" : "ERROR: [400] Both (name from query-parameter, name of the subject to delete) must be equal, but are (revoke.attempt.key.mismatch, revoke.attempt.key)"
}
generated on 2026-08-10 03:08:49 for branch HEAD